/*
 * Copyright (C) 2008 ZXing authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.zxing.client.android;

import java.io.IOException;
import java.util.Collection;
import java.util.EnumSet;
import java.util.Set;

import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.Result;
import com.google.zxing.ResultMetadataType;
import com.google.zxing.ResultPoint;
import com.google.zxing.client.android.camera.CameraManager;
import com.oniontech.stamptour.R;
import com.oniontech.stamptour.common.ui.CustomDialog;
import com.oniontech.stamptour.common.ui.DefaultActivity;

// TODO: Auto-generated Javadoc
/**
 * This activity opens the camera and does the actual scanning on a background thread. It draws a
 * viewfinder to help the user place the barcode correctly, shows feedback as the image processing
 * is happening, and then overlays the results when a scan is successful.
 *
 * @author dswitkin@google.com (Daniel Switkin)
 * @author Sean Owen
 */
public final class CaptureActivity extends DefaultActivity implements SurfaceHolder.Callback {

  /**
   * Instantiates a new capture activity.
   */
  public CaptureActivity()
	{
	  super(CaptureActivity.class.getSimpleName());
		// TODO Auto-generated constructor stub
	}

/** The Constant TAG. */
private static final String TAG = CaptureActivity.class.getSimpleName();


  /** The Constant DEFAULT_INTENT_RESULT_DURATION_MS. */
  private static final long DEFAULT_INTENT_RESULT_DURATION_MS = 1500L;
  
  /** The Constant BULK_MODE_SCAN_DELAY_MS. */
  private static final long BULK_MODE_SCAN_DELAY_MS = 1000L;

  /** The Constant PRODUCT_SEARCH_URL_PREFIX. */
  private static final String PRODUCT_SEARCH_URL_PREFIX = "http://www.google";
  
  /** The Constant PRODUCT_SEARCH_URL_SUFFIX. */
  private static final String PRODUCT_SEARCH_URL_SUFFIX = "/m/products/scan";
  
  /** The Constant ZXING_URLS. */
  private static final String[] ZXING_URLS = { "http://zxing.appspot.com/scan", "zxing://scan/" };
  
  /** The Constant RETURN_URL_PARAM. */
  private static final String RETURN_URL_PARAM = "ret";

  /** The Constant HISTORY_REQUEST_CODE. */
  public static final int HISTORY_REQUEST_CODE = 0x0000bacc;

  /** The Constant DISPLAYABLE_METADATA_TYPES. */
  private static final Set<ResultMetadataType> DISPLAYABLE_METADATA_TYPES =
      EnumSet.of(ResultMetadataType.ISSUE_NUMBER,
                 ResultMetadataType.SUGGESTED_PRICE,
                 ResultMetadataType.ERROR_CORRECTION_LEVEL,
                 ResultMetadataType.POSSIBLE_COUNTRY);

  /** The camera manager. */
  private CameraManager cameraManager;
  
  /** The handler. */
  private CaptureActivityHandler handler;
  
  /** The saved result to show. */
  private Result savedResultToShow;
  
  /** The viewfinder view. */
  private ViewfinderView viewfinderView;
  
  /** The status view. */
  private TextView statusView;
  
  /** The last result. */
  private Result lastResult;
  
  /** The has surface. */
  private boolean hasSurface;
  
  /** The source url. */
  private String sourceUrl;
  
  /** The return url template. */
  private String returnUrlTemplate;
  
  /** The decode formats. */
  private Collection<BarcodeFormat> decodeFormats;
  
  /** The character set. */
  private String characterSet;
  
  /** The version name. */
  private String versionName;
  
  /** The btn_help. */
  private Button btn_help;
  
  /** The m_b portrait. */
  private boolean m_bPortrait = true;
//  private InactivityTimer inactivityTimer;


  
  //url 체크 값
  /** The Constant CHECK_URL_NOT. */
private static final int CHECK_URL_NOT = -1;
  
  /** The Constant CHECK_URL_EVENT. */
  private static final int CHECK_URL_EVENT = 0;
  
  /** The Constant CHECK_URL_WEB. */
  private static final int CHECK_URL_WEB = 1;
  
  //이벤트 seq 값
  /** The event_seq. */
  private String event_seq = null;
  
  /** The cus dialog. */
  CustomDialog cusDialog;
  
  /**
   * Gets the viewfinder view.
   *
   * @return the viewfinder view
   */
  ViewfinderView getViewfinderView() {
    return viewfinderView;
  }

  /**
   * Gets the handler.
   *
   * @return the handler
   */
  public Handler getHandler() {
    return handler;
  }

  /**
   * Gets the camera manager.
   *
   * @return the camera manager
   */
  CameraManager getCameraManager() {
    return cameraManager;
  }

  /* (non-Javadoc)
   * @see com.oniontech.stamptour.common.ui.DefaultActivity#onCreate(android.os.Bundle)
   */
  @Override
  public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    
    m_AppContext = getApplicationContext();
    
    Window window = getWindow();
    window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    setContentView(R.layout.capture);

    hasSurface = false;
    
    cusDialog = new CustomDialog(CaptureActivity.this);


      LocationManager lm = (LocationManager) m_AppContext
              .getSystemService(Context.LOCATION_SERVICE);

      if (!lm.isProviderEnabled(LocationManager.GPS_PROVIDER) || !lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
          // gps 켜십시요!!!!! 안내 팝업

          final CustomDialog makedialog = new CustomDialog(CaptureActivity.this);
          makedialog.setDialogTitle(getResources().getString(
                  R.string.app_info));
          makedialog.setDialogMsg(getResources().getString(
                  R.string.GPS_DIALOG_INFO));
          makedialog.setBtnText("취소", "설정");
          makedialog.setCustomDialog(new OnClickListener() {
              @Override
              public void onClick(View v) {
                  // TODO Auto-generated method stub
                  switch (v.getId()) {
                      case R.id.btn_dial_confirm:
                          makedialog.Dismiss();
                          break;

                      case R.id.btn_dial_cancel:
                          // 설정
                          Intent intent = new Intent(
                                  android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                          startActivity(intent);
                          makedialog.Dismiss();
                          break;
                  }
              }
          }, true);

          makedialog.Show();
      }


      new Handler().postDelayed(new Runnable() {// 1 초 후에 실행
          @Override
          public void run() {
              // 실행할 동작 코딩
              setResult(RESULT_OK, null);
              finish();
          }
      }, 30000);

  }

  /* (non-Javadoc)
   * @see com.oniontech.stamptour.common.ui.DefaultActivity#onResume()
   */
  @Override
  protected void onResume() {
    super.onResume();

    // CameraManager must be initialized here, not in onCreate(). This is necessary because we don't
    // want to open the camera driver and measure the screen size if we're going to show the help on
    // first launch. That led to bugs where the scanning rectangle was the wrong size and partially
    // off screen.
    cameraManager = new CameraManager(getApplication());

    viewfinderView = (ViewfinderView) findViewById(R.id.viewfinder_view);
    viewfinderView.setCameraManager(cameraManager);

    statusView = (TextView) findViewById(R.id.status_view);

    handler = null;
    lastResult = null;

    resetStatusView();

    SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
    SurfaceHolder surfaceHolder = surfaceView.getHolder();
    if (hasSurface) {
      // The activity was paused but not stopped, so the surface still exists. Therefore
      // surfaceCreated() won't be called, so init the camera here.
      initCamera(surfaceHolder);
    } else {
      // Install the callback and wait for surfaceCreated() to init the camera.
      surfaceHolder.addCallback(this);
      surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    
//    inactivityTimer.onResume();

    Intent intent = getIntent();

//    source = IntentSource.NONE;
    decodeFormats = null;
    characterSet = null;

    if (intent != null) {

      String action = intent.getAction();
      String dataString = intent.getDataString();

      if (Intents.Scan.ACTION.equals(action)) {

        // Scan the formats the intent requested, and return the result to the calling activity.
//        source = IntentSource.NATIVE_APP_INTENT;
        decodeFormats = DecodeFormatManager.parseDecodeFormats(intent);

        if (intent.hasExtra(Intents.Scan.WIDTH) && intent.hasExtra(Intents.Scan.HEIGHT)) {
          int width = intent.getIntExtra(Intents.Scan.WIDTH, 0);
          int height = intent.getIntExtra(Intents.Scan.HEIGHT, 0);
          if (width > 0 && height > 0) {
            cameraManager.setManualFramingRect(width, height);
          }
        }
        
        String customPromptMessage = intent.getStringExtra(Intents.Scan.PROMPT_MESSAGE);
        if (customPromptMessage != null) {
          statusView.setText(customPromptMessage);
        }

      } else if (dataString != null &&
                 dataString.contains(PRODUCT_SEARCH_URL_PREFIX) &&
                 dataString.contains(PRODUCT_SEARCH_URL_SUFFIX)) {

        // Scan only products and send the result to mobile Product Search.
//        source = IntentSource.PRODUCT_SEARCH_LINK;
        sourceUrl = dataString;
        decodeFormats = DecodeFormatManager.PRODUCT_FORMATS;

      } else if (isZXingURL(dataString)) {

        // Scan formats requested in query string (all formats if none specified).
        // If a return URL is specified, send the results there. Otherwise, handle it ourselves.
//        source = IntentSource.ZXING_LINK;
        sourceUrl = dataString;
        Uri inputUri = Uri.parse(sourceUrl);
        returnUrlTemplate = inputUri.getQueryParameter(RETURN_URL_PARAM);
        decodeFormats = DecodeFormatManager.parseDecodeFormats(inputUri);

      }

      characterSet = intent.getStringExtra(Intents.Scan.CHARACTER_SET);

    }
  }

  /**
   * Checks if is z xing url.
   *
   * @param dataString the data string
   * @return true, if is z xing url
   */
  private static boolean isZXingURL(String dataString) {
    if (dataString == null) {
      return false;
    }
    for (String url : ZXING_URLS) {
      if (dataString.startsWith(url)) {
        return true;
      }
    }
    return false;
  }

  /* (non-Javadoc)
   * @see com.oniontech.stamptour.common.ui.DefaultActivity#onPause()
   */
  @Override
  protected void onPause() {
    if (handler != null) {
      handler.quitSynchronously();
      handler = null;
    }
//    inactivityTimer.onPause();
    cameraManager.closeDriver();
    if (!hasSurface) {
      SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
      SurfaceHolder surfaceHolder = surfaceView.getHolder();
      surfaceHolder.removeCallback(this);
    }
    super.onPause();
  }

  /* (non-Javadoc)
   * @see com.oniontech.stamptour.common.ui.DefaultActivity#onDestroy()
   */
  @Override
  protected void onDestroy() {
//    inactivityTimer.shutdown();
    super.onDestroy();
  }

  /* (non-Javadoc)
   * @see android.support.v4.app.FragmentActivity#onActivityResult(int, int, android.content.Intent)
   */
  @Override
  public void onActivityResult(int requestCode, int resultCode, Intent intent) {
  }

  /**
   * Decode or store saved bitmap.
   *
   * @param bitmap the bitmap
   * @param result the result
   */
  private void decodeOrStoreSavedBitmap(Bitmap bitmap, Result result) {
    // Bitmap isn't used yet -- will be used soon
    if (handler == null) {
      savedResultToShow = result;
    } else {
      if (result != null) {
        savedResultToShow = result;
      }
      if (savedResultToShow != null) {
//        Message message = Message.obtain(handler, R.id.decode_succeeded, savedResultToShow);
//        handler.sendMessage(message);
      }
      savedResultToShow = null;
    }
  }

  /* (non-Javadoc)
   * @see android.view.SurfaceHolder.Callback#surfaceCreated(android.view.SurfaceHolder)
   */
  @Override
  public void surfaceCreated(SurfaceHolder holder) {
    if (holder == null) {
      Log.e(TAG, "*** WARNING *** surfaceCreated() gave us a null surface!");
    }
    if (!hasSurface) {
      hasSurface = true;
      initCamera(holder);
    }
  }

  /* (non-Javadoc)
   * @see android.view.SurfaceHolder.Callback#surfaceDestroyed(android.view.SurfaceHolder)
   */
  @Override
  public void surfaceDestroyed(SurfaceHolder holder) {
    hasSurface = false;
  }

  /* (non-Javadoc)
   * @see android.view.SurfaceHolder.Callback#surfaceChanged(android.view.SurfaceHolder, int, int, int)
   */
  @Override
  public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

  }

  /**
   * Superimpose a line for 1D or dots for 2D to highlight the key features of the barcode.
   *
   * @param barcode   A bitmap of the captured image.
   * @param rawResult The decoded results which contains the points to draw.
   */
  private void drawResultPoints(Bitmap barcode, Result rawResult) {
    ResultPoint[] points = rawResult.getResultPoints();
    if (points != null && points.length > 0) {
      Canvas canvas = new Canvas(barcode);
      Paint paint = new Paint();
      paint.setColor(getResources().getColor(R.color.result_image_border));
      paint.setStrokeWidth(3.0f);
      paint.setStyle(Paint.Style.STROKE);
      Rect border = new Rect(2, 2, barcode.getWidth() - 2, barcode.getHeight() - 2);
      canvas.drawRect(border, paint);

      paint.setColor(getResources().getColor(R.color.result_points));
      if (points.length == 2) {
        paint.setStrokeWidth(4.0f);
        drawLine(canvas, paint, points[0], points[1]);
      } else if (points.length == 4 &&
                 (rawResult.getBarcodeFormat() == BarcodeFormat.UPC_A ||
                  rawResult.getBarcodeFormat() == BarcodeFormat.EAN_13)) {
        // Hacky special case -- draw two lines, for the barcode and metadata
        drawLine(canvas, paint, points[0], points[1]);
        drawLine(canvas, paint, points[2], points[3]);
      } else {
        paint.setStrokeWidth(10.0f);
        for (ResultPoint point : points) {
          canvas.drawPoint(point.getX(), point.getY(), paint);
        }
      }
    }
  }

  /**
   * Draw line.
   *
   * @param canvas the canvas
   * @param paint the paint
   * @param a the a
   * @param b the b
   */
  private static void drawLine(Canvas canvas, Paint paint, ResultPoint a, ResultPoint b) {
    canvas.drawLine(a.getX(), a.getY(), b.getX(), b.getY(), paint);
  }

   
  /**
   * Send reply message.
   *
   * @param id the id
   * @param arg the arg
   */
  private void sendReplyMessage(int id, Object arg) {
    Message message = Message.obtain(handler, id, arg);
    long resultDurationMS = getIntent().getLongExtra(Intents.Scan.RESULT_DISPLAY_DURATION_MS,
                                                     DEFAULT_INTENT_RESULT_DURATION_MS);
    if (resultDurationMS > 0L) {
      handler.sendMessageDelayed(message, resultDurationMS);
    } else {
      handler.sendMessage(message);
    }
  }

  /**
   * Inits the camera.
   *
   * @param surfaceHolder the surface holder
   */
  private void initCamera(SurfaceHolder surfaceHolder) {
    try {
      cameraManager.openDriver(surfaceHolder, m_bPortrait);
      // Creating the handler starts the preview, which can also throw a RuntimeException.
      if (handler == null) {
        handler = new CaptureActivityHandler(this, decodeFormats, characterSet, cameraManager);
      }
      decodeOrStoreSavedBitmap(null, null);
    } catch (IOException ioe) {
      Log.w(TAG, ioe);
      displayFrameworkBugMessageAndExit();
    } catch (RuntimeException e) {
      // Barcode Scanner has seen crashes in the wild of this variety:
      // java.?lang.?RuntimeException: Fail to connect to camera service
      Log.w(TAG, "Unexpected error initializing camera", e);
      displayFrameworkBugMessageAndExit();
    }
  }

  /**
   * Display framework bug message and exit.
   */
  private void displayFrameworkBugMessageAndExit() {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle(getString(R.string.app_name));
    builder.setMessage(getString(R.string.msg_camera_framework_bug));
    //xxxx
//    builder.setPositiveButton(R.string.button_ok, new FinishListener(this));
//    builder.setOnCancelListener(new FinishListener(this));
    builder.show();
  }

  /**
   * Restart preview after delay.
   *
   * @param delayMS the delay ms
   */
  public void restartPreviewAfterDelay(long delayMS) {
    if (handler != null) {
      handler.sendEmptyMessageDelayed(R.id.restart_preview, delayMS);
    }
    resetStatusView();
  }

  /**
   * Reset status view.
   */
  private void resetStatusView() {
    statusView.setText(R.string.msg_default_status);
    statusView.setVisibility(View.VISIBLE);
    viewfinderView.setVisibility(View.VISIBLE);
    lastResult = null;
  }

  /**
   * Draw viewfinder.
   */
  public void drawViewfinder() {
    viewfinderView.drawViewfinder();
  }
  
  /**
   * A valid barcode has been found, so give an indication of success and show the results.
   *
   * @param rawResult The contents of the barcode.
   * @param barcode   A greyscale bitmap of the camera data which was decoded.
   */
  public void handleDecode(Result rawResult, Bitmap barcode) {
    lastResult = rawResult;
//    Toast.makeText(this, rawResult.getText(), Toast.LENGTH_SHORT).show();

      restartPreviewAfterDelay(BULK_MODE_SCAN_DELAY_MS);


      Intent intent = new Intent();
      intent.putExtra("QR", rawResult.getText().trim());
      setResult(RESULT_OK, intent);
      finish();
    //테스트 코드
//    switch (checkUrl(lastResult.getText().trim())) {
//    	//이벤트 코드 확인
//	case CHECK_URL_EVENT:
//		break;
//
//		//web 호출
//	case CHECK_URL_WEB:
//		Toast.makeText(m_AppContext, "웹 호출!!!!", Toast.LENGTH_SHORT).show();
//		break;
//
//		//팝업 호출
//	case CHECK_URL_NOT:
//		break;
//	}
  }
  

  
  /*
   * QR 체크
   */
  /**
   * Check url.
   *
   * @param url the url
   * @return the int
   */
  public int checkUrl(String url) {
	  if(url.matches("(?i).*"+ "" + ".*")) {
		  return CHECK_URL_WEB;
	  }else if(url.matches("(?i).*event_seq=.*")) {
		  
		  int start = url.indexOf("event_seq=") + 10;
		  event_seq = url.substring(start);
		  return CHECK_URL_EVENT;	  	  
	  }else {
		  return CHECK_URL_NOT;
	  }
  }
}
